package me.winds.infrared.module.basic;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.widget.Toast;

import com.easyder.wrapper.utils.LogUtils;

import net.launchdigital.irsdk.IrSdk;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.ref.SoftReference;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;
import me.winds.infrared.AppConfig;
import me.winds.infrared.WrapperApplication;
import me.winds.infrared.module.basic.bean.IrBean;
import me.winds.infrared.utils.InfraredUtils;
import me.winds.widget.usage.ToastView;

/**
 * Author:  winds
 * Data:    2018/8/27
 * Version: 1.0
 * Desc:
 */


public class IrFactory {
    /**
     * 0  HotMetal
     * 1  Rainbow
     * 2  Gray
     * 3  HotSpot
     * 4  ColdSpot
     */
    protected int paletteNum;  //调色板 颜色编号
    protected IrSdk irSdk;
    protected IrBean irBean;
    protected boolean hasConnected; //判断是否连接成功过
    protected boolean isCameraOpen;

    protected int[] imageBuffer = new int[160 * 120];
    protected double[] tempBuffer = new double[320 * 240];

    private IrFactory() {
        irBean = new IrBean();
    }

    private static class FactoryBuilder {
        private static IrFactory factory = new IrFactory();
    }

    public static IrFactory getFactory() {
        return FactoryBuilder.factory;
    }

    /**
     * 初始化
     */
    public void forceInit() {
        sendBroadcast(false);
        irSdk = new IrSdk(WrapperApplication.getInstance());
    }

    /**
     * 注册监听
     */
    public void register() {
        if (irSdk != null) {
            sendBroadcast(false);
            irSdk.register();
        }
    }

    /**
     * 解销注册
     */
    public void unregister() {
        if (irSdk != null) {
            irSdk.unregister();
            sendBroadcast(true);
        }
    }

    /**
     * 销毁
     */
    public void destroy() {
        if (irSdk != null) {
            try {
                irSdk.destroy();
                sendBroadcast(true);
            } catch (Exception e) {
            }
        }
    }

    public boolean isIrSdkReady() {
        return irSdk != null && irSdk.isIrSdkReady();
    }

    /**
     * 定时开启获取图片
     *
     * @param delay
     * @return
     */
    public Observable<IrBean> timer(long delay) {
        return Observable.interval(delay, 180, TimeUnit.MILLISECONDS)
                .map(new Function<Long, IrBean>() {
                    @Override
                    public IrBean apply(Long aLong) throws Exception {
                        return captureImage();
                    }
                })
                .filter(new Predicate<IrBean>() {
                    @Override
                    public boolean test(IrBean irBean) throws Exception {
                        if (!hasConnected) { //非连接成功过 判断
                            hasConnected = irBean.ready;
                        }
                        return irBean.ready;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Deprecated
    public void takePicture() {
        if (irSdk.isIrSdkReady()) {
            Observable.just(irBean)
                    .map(new Function<IrBean, SoftReference<Bitmap>>() {
                        @Override
                        public SoftReference<Bitmap> apply(IrBean irBean) throws Exception {
                            return new SoftReference<>(irBean.bitmap);
                        }
                    })
                    .map(new Function<SoftReference<Bitmap>, String>() {
                        @Override
                        public String apply(SoftReference<Bitmap> bitmapSoftReference) throws Exception {
                            if (bitmapSoftReference != null) {
                                Bitmap bitmap = bitmapSoftReference.get();
                                if (bitmap != null) {
                                    return InfraredUtils.saveImage(bitmap);
                                }
                            }
                            return "";
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<String>() {
                        @Override
                        public void accept(String s) throws Exception {
                            if (!TextUtils.isEmpty(s)) {
                                try {
                                    File file = new File(s);
                                    MediaStore.Images.Media.insertImage(WrapperApplication.getInstance().getContentResolver(),
                                            file.getAbsolutePath(), file.getName(), null);
                                    WrapperApplication.getInstance().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                                            Uri.fromFile(file)));
                                } catch (FileNotFoundException e) {
                                    e.printStackTrace();
                                }
                                LogUtils.info("图片保存在" + s);
                                showToast("图片保存在" + s);
                            } else {
                                showToast("保存失败");
                            }
                        }
                    });
        } else {
            showToast("红外设备未连接");
        }
    }

    /**
     * 拍照
     *
     * @param showCenter
     */
    public void takePicture(boolean showCenter) {
        if (irSdk != null && irSdk.isIrSdkReady()) {
            InfraredUtils.takePicture(imageBuffer, irBean.centerTemp, showCenter);
        } else {
            showToast("红外设备未连接");
        }
    }

    /**
     * 設置調色板
     */
    public void setPalette() {
        if (irSdk != null && irSdk.isIrSdkReady()) {
//            irSdk.
            irSdk.setColormap(IrFactory.getFactory().getPaletteNum());
        } else {
            showToast("红外设备未连接");
        }
    }

    /**
     * 获取调色板模式
     *
     * @return
     */
    public int getPaletteNum() {
        if (paletteNum < 4) {
            paletteNum++;
        } else {
            paletteNum = 0;
        }
        return paletteNum;
    }

    public IrBean getIrBean() {
        return irBean;
    }

    /**
     * 截取一张图片
     *
     * @return
     */
    protected IrBean captureImage() {
        irBean.ready = false;
        if (irSdk != null && irSdk.isIrSdkReady()) {
            if (0 == irSdk.captureImage(imageBuffer, AppConfig.SIZE_HEIGHT * AppConfig.SIZE_WIDTH * Integer.BYTES,
                    tempBuffer, 320 * 240 * Double.BYTES)) {
                irBean.setData(imageBuffer, tempBuffer);
            }
        }
        return irBean;
    }

    protected void showToast(String msg) {
        ToastView.showToastInCenter(WrapperApplication.getInstance(), msg, Toast.LENGTH_SHORT);
    }

    /**
     * 设置开启usb摄像头
     * @param isFinish
     */
    private void sendBroadcast(boolean isFinish) {
        try {
            isCameraOpen = !isFinish;
            Intent intent = new Intent();
            intent.setAction(isFinish ? "agui.intent.action.USB_CAMREA_CLOSE" : "agui.intent.action.USB_CAMREA_OPEN");
            WrapperApplication.getInstance().sendBroadcast(intent);
        } catch (Exception e) {
        }
    }

    public boolean isHasConnected() {
        return hasConnected;
    }

//    public boolean isCameraOpen() {
//        return isOpen;
//    }
//
//    public void setCameraOpen(boolean bool) {
//        try{
//            Intent intent = new Intent();
//            intent.setAction(bool ? "agui.intent.action.USB_CAMERA_CLOSE" : "agui.intent.action.USB_CAMERA_OPEN");
//            WrapperApplication.getInstance().sendBroadcast(intent);
//            this.isOpen = bool;
//        }catch (Exception e){}
//
//    }
}
